package com.yantong.service.impl;

import com.yantong.utils.PageUtils;
import com.yantong.pojo.Order;
import com.yantong.pojo.TradeConfig;
import com.yantong.service.ConfigService;
import com.yantong.pojo.Integral;
import com.yantong.pojo.IntegralExample;
import com.yantong.pojo.IntegralLog;
import com.yantong.pojo.Member;
import com.yantong.mapper.IntegralLogMapper;
import com.yantong.mapper.IntegralMapper;
import com.yantong.mapper.MemberMapper;
import com.yantong.service.MemberIntegralService;
import com.yantong.utils.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author kanghaixin
 * @date 2018/9/13.20:29
 */

@Service
public class MemberIntegralServiceImpl implements MemberIntegralService {
	private static final Logger logger = LoggerFactory.getLogger(MemberIntegralServiceImpl.class);

	@Autowired
	private IntegralMapper integralMapper;
	@Autowired
	private IntegralLogMapper integralLogMapper;
	@Autowired
	private ConfigService configService;
	@Autowired
	private MemberMapper memberMapper;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int addMemberIntegral(Long mid, BigDecimal quantity, Long orderId, String detailed) {
		if (mid == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		Integral memberIntegral = integralMapper.getMemberIntegral(mid);

		// 没有查询到该会员在该站点下的积分钱包时做新增会员站点积分记录
		if (memberIntegral == null) {
			memberIntegral = new Integral();
			memberIntegral.setMid(mid);
			memberIntegral.setIntegral(BigDecimal.ZERO);
			integralMapper.insertSelective(memberIntegral);
		}

		Integral integral = new Integral();
		integral.setMid(mid);
		integral.setIntegral(quantity);

		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(detailed);
		log.setQuantity(integral.getIntegral());
		log.setType(1);
		log.setOrderId(orderId);
		integralLogMapper.insertSelective(log);

		return integralMapper.addIntegral(integral);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int obtainIntegral(Long mid, double quantity, Long orderId, String detailed) {
		if (mid == null || quantity <= 0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		Integral integral = new Integral();
		integral.setMid(mid);
		integral.setIntegral(new BigDecimal(quantity));

		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(detailed);
		log.setQuantity(integral.getIntegral());
		log.setType(1);
		log.setOrderId(orderId);
		integralLogMapper.insertSelective(log);
		return integralMapper.addIntegral(integral);
	}

	@Override
	public int obtainIntegral(Long mid, Long centreId, BigDecimal price, Integer credit, Long orderId,
			String detailed) {
		if (mid == null) {
			return 0;
		}
		Integral integral = new Integral();
		integral.setMid(mid);
		if (credit != null && credit > 0) {
			integral.setIntegral(BigDecimal.valueOf(credit));
		} else {
			TradeConfig tc = configService.getTradeConfig(centreId);
			if (tc != null) {
				if (tc.getSendIntegral() != null) {
					integral.setIntegral(price.multiply(BigDecimal.valueOf(tc.getSendIntegral())));
				}
			}
		}
		if (integral.getIntegral() == null || integral.getIntegral().doubleValue() <= 0) {
			return 0;
		}
		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(detailed);
		log.setQuantity(integral.getIntegral());
		log.setType(1);
		log.setOrderId(orderId);
		integralLogMapper.insertSelective(log);
		return integralMapper.addIntegral(integral);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int consumerIntegral(Long mid, double quantity, String detailed) {
		if (mid == null || quantity <= 0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		Integral integral = new Integral();
		integral.setMid(mid);
		integral.setIntegral(new BigDecimal(-quantity));

		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(detailed);
		log.setQuantity(new BigDecimal(quantity));
		log.setType(1);
		integralLogMapper.insertSelective(log);
		return integralMapper.addIntegral(integral);
	}

	@Override
	public PageUtils<IntegralLog> getIntegralLogs(Long centreId,Long teamId, String name, Date start, Date end, int offset,
			int limit) {
		PageUtils<IntegralLog> pageUtils = new PageUtils<>();

		Map<String, Object> params = new HashMap<>(4);
		if (centreId != null) {
			params.put("centreId", centreId);
		}
		if (teamId != null) {
			params.put("teamId", teamId);
		}
		if (StringUtils.isNotEmpty(name)) {
			params.put("name", name);
		}
		if (start != null) {
			params.put("start", start);
		}
		if (end != null) {
			params.put("end", end);
		}

		int total = integralLogMapper.countByParams(params);
		if (total > 0) {
			pageUtils.setTotal(total);
			pageUtils.setRows(integralLogMapper.listByParams(params, new RowBounds(offset, limit)));
		}
		return pageUtils;
	}


	@Override
	public PageUtils<IntegralLog> getIntegralLogsBefore(Long mid, Integer type, Date start, Date end, int offset, int limit) {
		PageUtils<IntegralLog> pageUtils = new PageUtils<>();

		Map<String, Object> params = new HashMap<>(4);
		if (mid != null) {
			params.put("mid", mid);
		}
		if (type != null) {
			params.put("type", type);
		}
		if (start != null) {
			params.put("start", start);
		}
		if (end != null) {
			params.put("end", end);
		}

		int total = integralLogMapper.countByParams(params);
		if (total > 0) {
			pageUtils.setTotal(total);
			List<IntegralLog> list = integralLogMapper.listByParams(params, new RowBounds(offset, limit));
			for (IntegralLog log : list) {
				if (log.getType().equals(0)) {
					log.setRemark1("消费积分");
				} else if (log.getType().equals(1)) {
					log.setRemark1("赠送积分");
				} else if (log.getType().equals(2)) {
					log.setRemark1("退还积分");
				} else {
					log.setRemark1("其他");
				}
			}
			pageUtils.setRows(list);
		}
		return pageUtils;
	}


	@Override
	public PageUtils<IntegralLog> getIntegralLogs(Long centreId,Long teamId,Long mid, String name, Date start, Date end, int offset, int limit) {
		PageUtils<IntegralLog> pageUtils = new PageUtils<>();

		Map<String, Object> params = new HashMap<>(4);
		if (centreId != null) {
			params.put("centreId", centreId);
		}
		if (teamId != null) {
			params.put("teamId", teamId);
		}
		if (mid != null) {
			params.put("mid", mid);
		}
		if (StringUtils.isNotEmpty(name)) {
			params.put("name", name);
		}
		if (start != null) {
			params.put("start", start);
		}
		if (end != null) {
			params.put("end", end);
		}

		int total = integralLogMapper.countByParams(params);
		if (total > 0) {
			pageUtils.setTotal(total);
			pageUtils.setRows(integralLogMapper.listByParams(params, new RowBounds(offset, limit)));
		}
		return pageUtils;
	}

	@Override
	public List<IntegralLog> listIntegralLogs(Long centreId, String name, Date start, Date end) {
		Map<String, Object> params = new HashMap<>(4);
		if (centreId != null) {
			params.put("centreId", centreId);
		}
		if (StringUtils.isNotEmpty(name)) {
			params.put("name", name);
		}
		if (start != null) {
			params.put("start", start);
		}
		if (end != null) {
			params.put("end", end);
		}
		return integralLogMapper.listByParams(params);
	}

	@Override
	public double getMemberIntegral(Long mid) {
		if (mid == null) {
			return 0d;
		}
		IntegralExample ie = new IntegralExample();
		ie.or().andMidEqualTo(mid);

		List<Integral> list = integralMapper.selectByExample(ie);
		if (CollectionUtils.isNotEmpty(list)) {
			Integral integral = list.get(0);
			return integral.getIntegral().doubleValue();
		}
		return 0d;
	}

	@Override
	public int grantIntegralNew(Long mid, Long centreId, BigDecimal price, Integer credit, Long orderId, Long opid,
			String nickName, String productName) {
		if (mid == null || centreId == null) {
			return 0;
		}

		BigDecimal jsIntegral = new BigDecimal("0");// 结算积分值
		Integer jsType = 0;// 结算类型
		// 发放积分
		if (credit != null && credit > 0) {
			// 如果该商品有积分值，则直接设值
			jsIntegral = BigDecimal.valueOf(credit);
			jsType = 1;
		} else {
			// 否则查询站点配置按每1元赠送积分数配置赠送
			TradeConfig tc = configService.getTradeConfig(centreId);
			if (tc != null) {
				if (tc.getSendIntegral() != null) {
					jsIntegral = price.multiply(BigDecimal.valueOf(tc.getSendIntegral()));
				}
			}
			jsType = 2;
		}
		// 如果发放积分值
		if (jsIntegral == null || jsIntegral.doubleValue() <= 0) {
			return 0;
		}

		// 通过会员编号站点站点编号获取 会员站点积分钱包
		Map<String, Object> queryMap = new HashMap<>();
		queryMap.put("mid", mid);
		//queryMap.put("centreid", centreId);
		Integral integral = integralMapper.selectByMIDCentreId(queryMap);

		// 没有查询到该会员在该站点下的积分钱包时做新增会员站点积分记录
		if (integral == null) {
			integral = new Integral();
			integral.setMid(mid);
			integral.setTname(nickName);
			integral.setUsername(nickName);
			integral.setIntegral(jsIntegral);
			integral.setCentreid(centreId);
			integralMapper.insertSelective(integral);
		} else {
			// 如果存在积分钱包，则做更新
			Map<String, Object> updMap = new HashMap<>();
			updMap.put("mid", mid);
			updMap.put("centreid", centreId);
			updMap.put("jsIntegral", jsIntegral);
			integralMapper.updateIntegerByMap(updMap);
		}
		// 生成积分记录
		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(productName);
		log.setQuantity(jsIntegral);
		log.setType(1);// 购买商品赠送积分
		log.setOrderId(orderId);
		log.setCentreid(centreId);
		log.setDesc("{orderId:" + orderId + ",opid:" + opid + ",centreId:" + centreId + ",jsType:" + jsType + "}");// 订单ID,商品ID,结算积分,结算类型1：本身商品积分结算2：站点配置按每1元赠送积分数配置赠送
		return integralLogMapper.insertSelective(log);

	}

	@Override
	public double getMemberIntegralNew(Long id) {
		Member member = memberMapper.selectByPrimaryKey(id);
		// 通过会员编号站点站点编号获取 会员站点积分钱包
		Map<String, Object> queryMap = new HashMap<>();
		queryMap.put("mid", id);
		//queryMap.put("centreid", member.getCentreId());
		Integral integral = integralMapper.selectByMIDCentreId(queryMap);
		return integral == null ? 0 : integral.getIntegral().doubleValue();
	}

	@Override
	public int returnIntegralNew(Order order, double credit) {
		if (order.getMid() == null || credit <= 0 || order.getCentreId() == null) {
			logger.info("mid is null or credit lt 0");
			return 0;
		}
		// 查询会员积分帐户
		// 通过会员编号站点站点编号获取 会员站点积分钱包
		Map<String, Object> queryMap = new HashMap<>();
		queryMap.put("mid", order.getMid());
		queryMap.put("centreid", order.getCentreId());
		Integral integral = integralMapper.selectByMIDCentreId(queryMap);

		// 没有查询到该会员在该站点下的积分钱包时做新增会员站点积分记录
		if (integral == null) {
			integral = new Integral();
			integral.setMid(order.getMid());
			integral.setTname(order.getNickname());
			integral.setUsername(order.getNickname());
			integral.setIntegral(new BigDecimal(credit));
			integral.setCentreid(order.getCentreId());
			integralMapper.insertSelective(integral);
		} else {
			// 如果存在积分钱包，则做更新
			Map<String, Object> updMap = new HashMap<>();
			updMap.put("mid", order.getMid());
			updMap.put("centreid", new BigInteger(order.getCentreId() + ""));
			updMap.put("jsIntegral", credit);
			integralMapper.updateIntegerByMap(updMap);
		}
		// 生成积分退还记录
		// 生成积分记录
		IntegralLog log = new IntegralLog();
		log.setMid(order.getMid());
		log.setDetailed(order.getOrdersn() + ",全部取消,退还全部积分:"+credit);
		log.setDesc("商品全部取消");
		log.setQuantity(new BigDecimal(credit));
		log.setType(2);//取消订单退还积分
		log.setOrderId(order.getId());
		log.setCentreid(order.getCentreId());
		return integralLogMapper.insertSelective(log);
	}

	@Override
	public int consumerGrantIntegralNew(Order order, Integer integral) {
		if (order == null || order.getMid() == null || integral <= 0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		// 从会员积分帐户中扣除
		Map<String, Object> updMap = new HashMap<>();
		updMap.put("mid", order.getMid());
		//updMap.put("centreid", new BigInteger(order.getCentreId() + ""));
		updMap.put("jsIntegral", new BigDecimal(-integral));
		// 生成消费积分记录
		IntegralLog log = new IntegralLog();
		log.setMid(order.getMid());
		log.setDetailed(order.getOrdersn() + "消费积分:" + integral);
		log.setQuantity(new BigDecimal(integral + ""));
		log.setType(0);// 消费记录
		log.setOrderId(order.getId());
		log.setCentreid(null);
		integralLogMapper.insertSelective(log);
		return integralMapper.updateIntegerByMap(updMap);

	}

	@Override
	public int consumerGrantIntegralNew2(Order order) {
		if (order == null || order.getMid() == null || order.getPayIntegral().compareTo(BigDecimal.ZERO)<0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		// 从会员积分帐户中扣除
		//积分扣款
		Integral integralParam = new Integral();
		integralParam.setMid(order.getMid());
		integralParam.setIntegral(order.getPayIntegral());

		// 生成消费积分记录
		IntegralLog log = new IntegralLog();
		log.setMid(order.getMid());
		log.setDetailed(order.getOrdersn() + "消费积分:" + order.getPayIntegral());
		log.setQuantity(order.getPayIntegral());
		log.setType(0);// 消费记录
		log.setOrderId(order.getId());
		log.setCentreid(null);
		integralLogMapper.insertSelective(log);
		return integralMapper.subtractIntegral(integralParam);

	}

	@Override
	public int afterReturnIntegralNew(Order order, Integer credit) {
		if (order.getMid() == null || credit <= 0 || order.getCentreId() == null) {
			logger.info("mid is null or credit lt 0");
			return 0;
		}
		// 查询会员积分帐户
		// 通过会员编号站点站点编号获取 会员站点积分钱包
		Map<String, Object> queryMap = new HashMap<>();
		queryMap.put("mid", order.getMid());
		queryMap.put("centreid", order.getCentreId());
		Integral integral = integralMapper.selectByMIDCentreId(queryMap);

		// 没有查询到该会员在该站点下的积分钱包时做新增会员站点积分记录
		if (integral == null) {
			integral = new Integral();
			integral.setMid(order.getMid());
			integral.setTname(order.getNickname());
			integral.setUsername(order.getNickname());
			integral.setIntegral(new BigDecimal(credit));
			integral.setCentreid(order.getCentreId());
			integralMapper.insertSelective(integral);
		} else {
			// 如果存在积分钱包，则做更新
			Map<String, Object> updMap = new HashMap<>();
			updMap.put("mid", order.getMid());
			updMap.put("centreid", new BigInteger(order.getCentreId() + ""));
			updMap.put("jsIntegral", credit);
			integralMapper.updateIntegerByMap(updMap);
		}
		// 生成积分退还记录
		// 生成积分记录
		IntegralLog log = new IntegralLog();
		log.setMid(order.getMid());
		log.setDetailed(order.getOrdersn() + ",全部售后，退还积分:"+credit);
		log.setDesc("商品全部售后");
		log.setQuantity(new BigDecimal(credit));
		log.setType(3);//售后订单退还积分
		log.setOrderId(order.getId());
		log.setCentreid(order.getCentreId());
		return integralLogMapper.insertSelective(log);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int addMemberIntegral(Long mid, BigDecimal quantity, Long orderId, String detailed, String date, boolean is_bq) {
		if (mid == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
			logger.info("mid is null or quantity lt 0");
			return 0;
		}
		Integral memberIntegral = integralMapper.getMemberIntegral(mid);

		// 没有查询到该会员在该站点下的积分钱包时做新增会员站点积分记录
		if (memberIntegral == null) {
			memberIntegral = new Integral();
			memberIntegral.setMid(mid);
			memberIntegral.setIntegral(BigDecimal.ZERO);
			integralMapper.insertSelective(memberIntegral);
		}

		Integral integral = new Integral();
		integral.setMid(mid);
		integral.setIntegral(quantity);

		IntegralLog log = new IntegralLog();
		log.setMid(mid);
		log.setDetailed(detailed);
		log.setQuantity(integral.getIntegral());
		log.setType(1);
		log.setOrderId(orderId);
		if(is_bq){
			Date createTime = DateUtil.getStrByFormatDate(date,DateUtil.yyyy_MM_dd_HH_mm_ss);
			log.setCreateTime(createTime);
		}
		integralLogMapper.insertSelective(log);

		return integralMapper.addIntegral(integral);
	}

}
